<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: Dean <zxxjjforever@163.com>
// +----------------------------------------------------------------------
namespace api\wxapp\controller;

use think\Db;
use cmf\controller\RestBaseController;
use wxapp\aes\WXBizDataCrypt;
use think\Validate;
use app\common\service\MsgService;
class PublicController extends RestBaseController
{
    // 微信小程序用户登录 TODO 增加最后登录信息记录,如 ip
    public function login()
    {
        $validate = new Validate([
            'code'           => 'require',
            'encrypted_data' => 'require',
            'iv'             => 'require',
            'raw_data'       => 'require',
            'signature'      => 'require',
            'username' => 'require',
            'password' => 'require',
            'type' => 'require',
            'msg_code' => 'require',
        ]);

        $validate->message([
            'code.require'           => '缺少参数code!',
            'encrypted_data.require' => '缺少参数encrypted_data!',
            'iv.require'             => '缺少参数iv!',
            'raw_data.require'       => '缺少参数raw_data!',
            'signature.require'      => '缺少参数signature!',
            'username.require' => '请输入手机号或用户名!',
            'password.require' => '请输入您的密码!',
            'type.require' => '参数错误!',
            'msg_code.require' => '请输入您的验证码!',

        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->error($validate->getError());
        }

        //判断是手机号登录还是账号登录
        if ($type==1) {
            //手机号
            $findUserWhere['MOBILPHONE'] = $data['username'];
            $result = checkMobile($data['username'],$yzm);
            if(!$result){
                $this->error('验证码错误');
            }
        } else if ($type==2) {
            //账号
            $findUserWhere['USER_ID'] = $data['username'];
        } else {
            $this->error("请求错误,未知设备!");
        }
        $findUser = Db::name("rl_zsms_user_query")->where($findUserWhere)->find();
        if (empty($findUser)) {
            $this->error("用户不存在!");
        }else{
            //验证用户密码

            if(0)
            {
                $this->error("用户名或者密码错误!");
            }
        }

        $code          = $data['code'];
        $wxappSettings = cmf_get_option('wxapp_settings');

        $appId = $this->request->header('XX-Wxapp-AppId');
        if (empty($appId)) {
            if (empty($wxappSettings['default'])) {
                $this->error('没有设置默认小程序！');
            } else {
                $defaultWxapp = $wxappSettings['default'];
                $appId        = $defaultWxapp['app_id'];
                $appSecret    = $defaultWxapp['app_secret'];
            }
        } else {
            if (empty($wxappSettings['wxapps'][$appId])) {
                $this->error('小程序设置不存在！');
            } else {
                $appId     = $wxappSettings['wxapps'][$appId]['app_id'];
                $appSecret = $wxappSettings['wxapps'][$appId]['app_secret'];
            }
        }


        $response = cmf_curl_get("https://api.weixin.qq.com/sns/jscode2session?appid=$appId&secret=$appSecret&js_code=$code&grant_type=authorization_code");

        $response = json_decode($response, true);
        if (!empty($response['errcode'])) {
            $this->error('操作失败!');
        }

        $openid     = $response['openid'];
        $sessionKey = $response['session_key'];
        session('openid',$openid);
        $pc      = new WXBizDataCrypt($appId, $sessionKey);
        $errCode = $pc->decryptData($data['encrypted_data'], $data['iv'], $wxUserData);

        if ($errCode != 0) {
            $this->error('操作失败!');
        }

        $findThirdPartyUser = Db::name("third_party_user")
            ->where('openid', $openid)
            ->where('app_id', $appId)
            ->find();

        $currentTime = time();
        $ip          = $this->request->ip(0, true);

        $wxUserData['sessionKey'] = $sessionKey;
        unset($wxUserData['watermark']);

        if ($findThirdPartyUser) {
            $userId = $findThirdPartyUser['user_id'];
            $token  = cmf_generate_user_token($findThirdPartyUser['user_id'], 'wxapp');

            $userData = [
                'last_login_ip'   => $ip,
                'last_login_time' => $currentTime,
                'login_times'     => Db::raw('login_times+1'),
                'more'            => json_encode($wxUserData)
            ];

            if (isset($wxUserData['unionId'])) {
                $userData['union_id'] = $wxUserData['unionId'];
            }

            Db::name("third_party_user")
                ->where('openid', $openid)
                ->where('app_id', $appId)
                ->update($userData);

        } else {

            //TODO 使用事务做用户注册
            $userId = Db::name("user")->insertGetId([
                'create_time'     => $currentTime,
                'user_status'     => 1,
                'user_type'       => 2,
                'sex'             => $wxUserData['gender'],
                'user_nickname'   => $wxUserData['nickName'],
                'avatar'          => $wxUserData['avatarUrl'],
                'last_login_ip'   => $ip,
                'last_login_time' => $currentTime,
            ]);

            Db::name("third_party_user")->insert([
                'openid'          => $openid,
                'user_id'         => $userId,
                'third_party'     => 'wxapp',
                'app_id'          => $appId,
                'last_login_ip'   => $ip,
                'union_id'        => isset($wxUserData['unionId']) ? $wxUserData['unionId'] : '',
                'last_login_time' => $currentTime,
                'create_time'     => $currentTime,
                'login_times'     => 1,
                'status'          => 1,
                'more'            => json_encode($wxUserData)
            ]);

            $token = cmf_generate_user_token($userId, 'wxapp');

        }

        $user = Db::name('user')->where('id', $userId)->find();
        //向sms用户表里更新APPID
        if($findUser['APPID'] != $openid)
        {
            Db::name("rl_zsms_user_query")->where($findUserWhere)->update(['OPENID'=>$openid]);
        }
        $this->success("登录成功!", ['token' => $token, 'user' => $user, 'findUser' => $findUser]);


    }

           /**
     * 发送验证码
     */
    public function send(){
        $mobile  = trim(I('post.mobile',''));
        $referer_action = getRefererAction();
        $cache_mobile = session('send_code');//如果缓存存在手机号码，并且是找回密码操作，则获取缓存中的手机号码
        $mobile = ($cache_mobile && $referer_action == 'findPwdSecond') ? $cache_mobile : $mobile;
        // 验证手机号
        if(!preg_match("/^1\d{10}$/",$mobile)){
            $json['status'] = 2;
            $json['msg'] = '手机号格式不正确！';
            $this->ajaxReturn($json);
        }

        $is_mobile = M('ucenter_member')->where(array('mobile'=>"$mobile"))->getField('mobile');
//        $legal_request_arr = ['register','login','editMobileFirst','editMobileSecond','findPwdFirst','editMobile'];//合法请求地址
        $legal_request_arr = ['register','login','findPwdFirst','findPwdSecond','editMobile'];//合法请求地址

        if(($referer_action == 'register' || $referer_action == 'editMobile') && $is_mobile){
            $json['status'] = 2;
            $json['msg'] = '该手机号已注册！';
            $this->ajaxReturn($json);
        }elseif(($referer_action == 'findPwdFirst' || $referer_action == 'login' || $referer_action == 'editMobileFirst') && empty($is_mobile)){
            $json['status'] = 2;
            $json['msg'] = '该手机号尚未注册！';
            $this->ajaxReturn($json);
        }elseif(!in_array($referer_action,$legal_request_arr) ){
            $json['status'] = 2;
            $json['msg'] = '非法请求！';
            $this->ajaxReturn($json);
        }


        // 验证发送次数
        $start = strtotime(date('Y-m-d',time()));
        $stop = strtotime(date('Y-m-d',time()))+86400;
        $map['mobile'] = $mobile;
        $map['create_time'] = [['gt',$start],['lt',$stop]];
        $count = M('sms')->where($map)->count();

        if($count>10){
            $json['status'] = 2;
            $json['msg'] = '您今天发送的短信过多,请明天再试！';
            $this->ajaxReturn($json);
        }

        $code =  str_pad(rand(0,9999),4,0,STR_PAD_LEFT);
        $msgModel = new MsgService();
        $res = $msgModel->singlesender($code,$mobile);
        if($res['result'] == 0) {
            if($referer_action == 'findPwdFirst') session('send_code',$mobile);//找回密码操作，设置session防止外链
            $json['status'] = 1;
            $json['msg'] = '短信发送成功！';
            $this->ajaxReturn($json);
        }else{
            $json['status'] = 2;
            $json['msg'] = '系统繁忙，请稍后重试！';
            $this->ajaxReturn($json);
        }
    }

        /**
     * 检查验证码短信
     * @author
     */
    public function checkMobile($mobile,$yzm)
    {
        if (empty($mobile)) {
            $this->error = '手机号码不能为空！';
            return false;
        }

        if (!preg_match("/^1\d{10}$/", $mobile)) {
            $this->error = '手机号格式不正确！';
            return false;
        }

        $yam_info = session('yanzhen');
        if (!$yzm || $yzm != $yam_info['yzm'] || $mobile != $yam_info['mobile'] || ($yam_info['addtime'] + 300) < time()){
            $this->error = '短信验证码不正确！';
            return false;
        }
        session('yanzhen',null);
        return true;
    }

}
